package be.jaisy.project.adapter.factory;

import java.util.HashMap;
import java.util.Map;

import org.osgi.framework.Bundle;
import org.osgi.framework.ServiceFactory;

import be.jaisy.osgi.transaction.ITransactionManager;

/**
 * Allows the application to define units of work, while maintaining abstraction from the underlying transaction implementation (eg.
 * JTA, JDBC).
 * 
 * @author Stany Blanvalet
 */
public abstract class TransactionFactory implements ServiceFactory {
	
	/**
	 * Creates a standalone TransactionFactory that returns Hibernate Session for use
	 * in any environment Hibernate has been configured for. 
	 */
	public static final String HIBERNATE = "be.jaisy.project.adapter.factory.impl.HibernateTransactionFactoryImpl";

	private static Map<String, TransactionFactory> factories = new HashMap<String, TransactionFactory>(); 
	
	/**
	 * Factory method for instantiation of concrete factories.
	 */
	public static TransactionFactory instance(String factoryName, Bundle bundle) {
		
		TransactionFactory factory = factories.get(factoryName);
		if(factory==null){
			try {
				Class factoryClass = bundle.loadClass(factoryName);
				factory = (TransactionFactory) factoryClass.newInstance();				
			} catch (Exception ex) {
				throw new RuntimeException("Couldn't create TransactionFactory [" + factoryName + "]: " + ex.getMessage());
			}
			factories.put(factoryName, factory);			
		}
		return factory;
	}
	
	/**
	 * return the specific ITransactionManager.
	 */
	public abstract ITransactionManager getTransactionManager();
}
